package mian;

import entities.Player;
import levels.LevelManager;

import java.awt.*;

public class Game implements Runnable{
    public final static float SCALE=1.5F; //比例
    public final static int TILES_DEFAULT_SIZE=32;//基本图块大小
    public final static int TILES_IN_WIDTH=26;//横向图块数
    public final static int TILE_IN_HEIGHT=14;//纵向图块数
    public final static int TILE_SIZE=(int)(TILES_DEFAULT_SIZE*SCALE);//实际图块
    public final static int GAME_WIDTH=TILE_SIZE*TILES_IN_WIDTH;//实际游戏画面宽度
    public final static int GAME_HEIGHT=TILE_SIZE*TILE_IN_HEIGHT;//实际游戏画面高度

    private LevelManager levelManager;
    private Player player;
    private GameWindow gameWindow;
    private GamePanel gamePanel;
    private Thread gameThread;
    private final int FPS_SET=120;
    private final int UPS_SET=200;

    public Game(){
        initClasses();
        gamePanel = new GamePanel(this);
        gameWindow = new GameWindow(gamePanel);
        gamePanel.setFocusable(true);
        gamePanel.requestFocus();
        startGameLoop();
    }
    public void run(){
        double deltaU=0;
        double deltaF=0;
        double timePerFrame=1000000000.0/FPS_SET;
        double timePerUpdate=1000000000.0/UPS_SET;
        long previousTime=System.nanoTime();
        long lastFrame=System.nanoTime();
        long now=System.nanoTime();
        int frames=0;
        int updataes=0;
        long lastCheck=System.currentTimeMillis();
        while (true){
            now=System.nanoTime();
            long currentime=System.nanoTime();
            deltaU+=(currentime-previousTime)/timePerUpdate;
            deltaF+=(currentime-previousTime)/timePerFrame;
            previousTime=currentime;
            if (deltaU>=1){
              update();
                updataes++;
                deltaU--;
            }
            if (deltaF>=1){
                gamePanel.repaint();
                frames++;
                deltaF--;
            }
            if(now-lastFrame>=timePerFrame){
                gamePanel.repaint();
                lastFrame=now;
                frames++;
            }
            if(System.currentTimeMillis()-lastCheck>=1000){
                lastCheck=System.currentTimeMillis();
                System.out.println("FPS:"+frames+"|UPS:"+updataes);
                frames=0;
                updataes=0;
            }
        }
    }

    private void update() {
        player.update();
        levelManager.update();
    }

    public void startGameLoop(){
        gameThread=new Thread(this);
        gameThread.start();
    }
    public void initClasses(){
        player=new Player(200,200,(int)(64*SCALE),(int)(40*SCALE));
        levelManager=new LevelManager(this);
        player.loadLvlData(levelManager.getCurrentLevel().getLvlData());
    }
    public void render(Graphics g){
        player.render(g);
        levelManager.draw(g);
    }
    public Player getPlayer(){
        return player;
    }
    public void windowFocusLost(){
        player.resetDirBooleans();
    }
}
